package com.symaster.common.connect.v2;

import com.symaster.common.connect.util.ClientCommon;
import com.symaster.common.thread.WatchThread;
import com.symaster.common.util.IOUtil;

import java.io.Closeable;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.UUID;

public class RegistrationCenter extends WatchThread implements Closeable {

    private final DatagramSocket datagramSocket;
    private ConnectionRequestListener connectionRequestListener;

    public RegistrationCenter(int port) {
        super(0, "symaster-registration-center-" + UUID.randomUUID());
        try {
            datagramSocket = new DatagramSocket(port);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void setConnectionRequestListener(ConnectionRequestListener connectionRequestListener) {
        this.connectionRequestListener = connectionRequestListener;
    }

    @Override
    protected void execute() throws Exception {
        byte[] bytes = new byte[52];
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
        datagramSocket.receive(datagramPacket);
        InetAddress address = datagramPacket.getAddress();

        if (connectionRequestListener != null) {
            ConnectionRequestEntity nodeConnectData = getNodeConnectData(bytes);
            String hostAddress = address.getHostAddress();
            nodeConnectData.setIp(hostAddress);
            connectionRequestListener.handler(nodeConnectData);
        }
    }

    private ConnectionRequestEntity getNodeConnectData(byte[] bytes) {

        byte[] portBytes = {bytes[4], bytes[5], bytes[6], bytes[7]};
        int port = ClientCommon.byte2int(portBytes);
        ConnectionRequestEntity connectionRequestEntity = new ConnectionRequestEntity();
        connectionRequestEntity.setPort(port);
        return connectionRequestEntity;
    }

    @Override
    public void close() {
        stop();
        IOUtil.close(datagramSocket);
    }

    interface ConnectionRequestListener {
        void handler(ConnectionRequestEntity entity);
    }

    static class ConnectionRequestEntity {
        private String ip;
        private int port;

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }

        @Override
        public String toString() {
            return "ConnectionRequestEntity{" +
                    "ip='" + ip + '\'' +
                    ", port=" + port +
                    '}';
        }
    }
}